using System;
using System.Collections.Generic;
using System.Text;

namespace UserInterface.MML.Base
{
    internal static class Compiler
    {
        private static Dictionary<string, TagHandler> tagHandlers =
            new Dictionary<string, TagHandler>();
        
        internal static void RegisterTagHandler(string tagName, TagHandler tagHandler)
        {
            tagHandlers[tagName] = tagHandler;
        }

        internal static string Compile(ParseTree parseTree, object context)
        {
            return GetCompiledContent(parseTree, context);
        }

        internal static string GetCompiledContent(ItemContainer container, object context)
        {
            StringBuilder outputBuilder = new StringBuilder();
            foreach (IItem item in container.Items)
            {
                if (item is CharacterDataItem)
                {
                    CharacterDataItem characterDataItem = item as CharacterDataItem;
                    outputBuilder.Append(
                        TextFilterManager.Filter(characterDataItem.Data)    
                    );
                }
                else if (item is TagItem)
                {
                    TagItem tagItem = item as TagItem;
                    bool isHandled = false;
                    if (tagHandlers.ContainsKey(tagItem.Name))
                    {
                        TagHandler tagHandler = tagHandlers[tagItem.Name];
                        string output = tagHandler.Handle(tagItem, context);
                        if (output != null)
                        {
                            outputBuilder.Append(output);
                            isHandled = true;
                        }
                    }
                    if (!isHandled)
                    {
                        outputBuilder.Append(tagItem.StartTagCode);
                        outputBuilder.Append(GetCompiledContent(tagItem, context));
                        outputBuilder.Append(tagItem.EndTagCode);
                    }
                }
            }
            return outputBuilder.ToString();
        }

        internal static string GetOriginalContent(TagItem tagItem)
        {
            StringBuilder outputBuilder = new StringBuilder();
            foreach (IItem item in tagItem.Items)
            {
                if (item is CharacterDataItem)
                {
                    outputBuilder.Append(
                        ((CharacterDataItem)item).Data
                    );
                }
                else if (item is TagItem)
                {
                    TagItem subTagItem = item as TagItem;
                    outputBuilder.Append(subTagItem.StartTagCode);
                    outputBuilder.Append(GetOriginalContent(subTagItem));
                    outputBuilder.Append(subTagItem.EndTagCode);
                }
            }
            return outputBuilder.ToString();
        }
    }
}
